<template>
  <div
    v-if="hackReset"
    @click.prevent.stop="hasChild?expanded=!expanded:$emit('click',node,$event);"
    @dblclick.prevent.stop="$emit('dblclick',node,$event)"
    @contextmenu.prevent.stop="$emit('contextmenu',node,$event)"
  >
    <div v-if="tableModel" class="list-node table-node">
      <span :class="['list-node-icon table-node-text',{[expanded?'far fa-minus-square':'far fa-plus-square']:hasChild}]" />
      <span v-for="(item,key) in node" :key="key" class="list-node-text table-node-text">{{ item }}</span>
    </div>
    <div v-else class="list-node">
      <i
        v-if="mutliSelect"
        :class="node.checked?'fas fa-check-circle':'far fa-circle'"
        @click.prevent.stop="nodeClick(node,$event)"
        @dblclick.prevent.stop="nodeDblClick(node,$event)"
      />
      <icon-show v-if="showIcon" class="list-node-icon" :src="node" />
      <i v-else :class="['list-node-icon',{[expanded?'far fa-minus-square':'far fa-plus-square']:hasChild}]" />
      <span class="list-node-text" :title="node.info?node.info.hint:node[treeTemplate.label]">{{ node[treeTemplate.label] }}</span>
      <i :class="['list-node-icon',{[expanded?'fa fa-angle-up':'fa fa-angle-down']:hasChild}]" />
    </div>
    <TreeListTempalte
      v-for="(item, index) in children"
      v-show="expanded"
      :key="index"
      class="list-child"
      :node="item"
      :data="data"
      :tree-template="treeTemplate"
      :expand="expand"
      :show-icon="showIcon"
      :mutli-select="mutliSelect"
      :table-model="tableModel"
      :table-template="tableTemplate"
      @click="$emit('click',$event)"
      @dblclick="$emit('dblclick',$event)"
      @contextmenu="$emit('contextmenu',$event)"
    />
  </div>
</template>
<script>
export default {
  name: 'TreeListTempalte',
  props: {
    node: {
      type: Object,
      required: true,
      default: () => {}
    },
    data: {
      type: Array,
      required: true,
      default: () => []
    },
    treeTemplate: {
      type: Object,
      required: false,
      default: () => ({
        label: 'name',
        key: 'item_uid',
        parent: 'parent_uid'
      })
    },
    expand: {
      type: Boolean,
      required: false,
      default: false
    },
    showIcon: {
      type: Boolean,
      required: false,
      default: false
    },
    mutliSelect: {
      type: Boolean,
      required: false,
      default: false
    },
    tableModel: {
      type: Boolean,
      required: false,
      default: true
    },
    tableTemplate: {
      type: Object,
      required: false,
      default: () => ({
        id: { name: 'ID' },
        name: { name: '名称' },
        flag: { name: '标识' }
      })
    }
  },
  data() {
    return {
      hackReset: true,
      expanded: this.expand
    }
  },
  computed: {
    children() {
      return this.data && this.node && this.node[this.treeTemplate.key]
        ? this.data.filter(item => item[this.treeTemplate.parent] === this.node[this.treeTemplate.key])
        : []
    },
    hasChild() {
      return this.children && this.children.length > 0
    },
    nodeData() {
      return Object.keys(this.tableTemplate).reduce((result, key) => ({ ...result, [key]: this.node ? this.node[key] : null }), {})
    }
  },
  watch: {
    expand(val, oldval) {
      this.expanded = val
    }
  },
  // for mutli select component
  methods: {
    nodeDblClick(data, event) {
      data.checked = !data.checked
    },
    nodeClick(data, event) {
      data.checked = !data.checked
      if (this.mutliSelect) {
        for (const item of this.data) {
          if (item.branch.indexOf(data.id) !== -1) {
            item.checked = data.checked
          }
        }
        this.refresh()
      }
    },
    refresh(event) {
      this.hackReset = false
      this.$nextTick(() => {
        this.hackReset = true
      })
    }
  }
}
</script>
<style scoped>
.list-node {
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between;
  align-items: center;
  padding: .5rem 0;
}
.list-node:hover {
  background-color: gray !important;
}
.list-node-text {
  flex-grow: 1;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.list-node-icon {
  padding: 0 .5rem;
}
.list-child {
  padding-left: 1rem;
}

/* display of table model only */
.table-node {
  border: .1rem;
  border-color: blue;
  border-style: solid;
}
.table-node-text {
  border: .1rem;
  border-color: red;
  border-style: solid;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
